/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.expandable.util;

import java.math.BigDecimal;

/**
 * ex.
 * AnimatorValueUtil animatorValueUtil = new AnimatorValueUtil();
 * animatorValueUtil.ofFloat(0.1f,-3f,2f)
 * public void onUpdate(AnimatorValue animatorValue, float v) {
 * float currentV = animatorValueUtil.getValue(v);
 * }
 *
 * @since 2021-04-06
 */
public class AnimatorValueUtil {
    private static final String TAG = "AnimatorValueUtil";
    private static final int RATESIZE = 2;
    private static final int NEGATIVE = -1;

    private float[] values;
    private float[][] rate;

    /**
     * 设置动画区间
     *
     * @param values 动画区间值
     */
    public void setValues(float[] values) {
        if (values == null) {
            this.values = null;
        } else {
            this.values = (float[]) values.clone();
        }
    }

    /**
     * 获取动画值区间
     *
     * @return float数组
     */
    public float[] getValues() {
        return (float[]) values.clone();
    }

    /**
     * 如传一个参数，则getValue 返回值与传入的 V 值一致
     * 如传入连续两个相同参数，则会出现除0异常
     * 传参试例: 0.8f,-1.2f,3.5f,0,5
     *
     */
    public void ofFloat() {
        rate = new float[this.getValues().length - 1][RATESIZE];
        float sum = 0;
        for (int index = 1; index < this.getValues().length; index++) {
            sum += Math.abs(this.getValues()[index] - this.getValues()[index - 1]);
        }

        // 计算每个变化值的占比和达到该变化值系数
        for (int index = 0; index < rate.length; index++) {
            float tempRate = Math.abs((this.getValues()[index + 1] - this.getValues()[index]) / sum);
            rate[index][0] = tempRate + (index == 0 ? 0 : rate[index - 1][0]);
            float tempDuration = this.getValues()[index + 1] - this.getValues()[index];
            rate[index][1] = (this.getValues()[index] > this.getValues()[index + 1]
                ? NEGATIVE : 1) * Math.abs(tempDuration / tempRate);
        }
    }

    /**
     * 根据 属性动画中value的值，计算当前值
     *
     * @param value 属性动画中的value
     * @return 通过计算后的值
     */
    public float getValue(float value) {
        for (int index = 0; index < rate.length; index++) {
            // 如果是进入当前变化值占比，则按当前系数进行计算实际值(bounce回弹效果最后v会大于1)
            if (value <= rate[index][0] || value > 1) {
                float amintorValue;
                if (index == 0) {
                    amintorValue = value;
                } else {
                    amintorValue = new BigDecimal(value).subtract(new BigDecimal(rate[index - 1][0])).floatValue();
                }
                return new BigDecimal(amintorValue).multiply(new BigDecimal(rate[index][1])).add(
                    new BigDecimal(getValues()[index])).floatValue();
            }
        }
        return value;
    }
}
